#!/usr/bin/ruby -Ku
# -*- coding: utf-8 -*-
require 'test/unit'
require 'm3g'

class Test_Transform < Test::Unit::TestCase
  def setup
  end

  def teadown
  end

  def test_defualt_variables
    trns = M3G::Transform.new
    m0 = trns.matrix
    m1 = [1,0,0,0,
          0,1,0,0,
          0,0,1,0,
          0,0,0,1]
    for i in 0..15
      assert_in_delta m1[i], m0[i], 0.0001
    end
  end

  def test_set_variables_1
    trns = M3G::Transform.new
    m0   = [10,2,3,4,
            5,60,7,8,
            9,10,110,12,
            13,14,15,160]
    trns.matrix = m0
    m1 = trns.matrix
    for i in 0..15
      assert_in_delta m0[i], m1[i], 0.0001
    end
    
    trns2 = M3G::Transform.new trns
    m4 = trns.matrix
    m5 = trns2.matrix
    for i in 0..15
      assert_in_delta m5[i], m4[i], 0.0001
    end

    trns3 = M3G::Transform.new
    trns3.matrix = trns
    m8 = trns.matrix
    m9 = trns3.matrix
    for i in 0..15
      assert_in_delta m9[i], m8[i], 0.0001
    end
    
  end

  def test_set_variables_2
    trns = M3G::Transform.new
    m1   = [10,5,9,13,
            2,60,10,14,
            3,7,110,15,
            4,8,12,160]
    trns.matrix = m1

    trns.transpose
    m2 = trns.matrix 
    m3 = [10,2,3,4,
          5,60,7,8,
          9,10,110,12,
          13,14,15,160]
    for i in 0..15
      assert_in_delta m3[i], m2[i], 0.0001
    end
    

    trns.invert
    m4 = trns.matrix
    m5 = [ 0.1065345,  -0.0025991,  -0.0024194,   -0.0023520,
          -0.0070484,   0.0171827,  -0.0008164,   -0.0006217,
          -0.0072731,  -0.0012209,   0.0094303,   -0.0004644,
          -0.0073573,  -0.0011778,  -0.0006161,    0.0065390]
    for i in 0..15
      assert_in_delta m5[i], m4[i], 0.0001
    end

    trns.identify
    m6 = trns.matrix
    m7 = [1,0,0,0,
          0,1,0,0,
          0,0,1,0,
          0,0,0,1]
    for i in 0..15
      assert_in_delta m7[i], m6[i], 0.0001
    end
  end

  def test_transform_1
    trns = M3G::Transform.new
    trns.matrix = [1,2,3,4, 5,6,7,8, 9,10,11,12, 13,14,15,16]

    v = [1,1,1,1, 2,2,2,2]   # 必ず4つ(x,y,z,w)ずつ
    trns.transform v
    assert_in_delta  10, v[0], 0.00001
    assert_in_delta  26, v[1], 0.00001
    assert_in_delta  42, v[2], 0.00001
    assert_in_delta  58, v[3], 0.00001
    assert_in_delta  20, v[4], 0.00001
    assert_in_delta  52, v[5], 0.00001
    assert_in_delta  84, v[6], 0.00001
    assert_in_delta 116, v[7], 0.00001
  end

  def test_transform_2
    trns = M3G::Transform.new
    trns.post_translate 1,2,3
    vin  = M3G::VertexArray.new 2, 3, 4
    vin.values[0,2] = [1,2,3, 4,5,6]      # x,y,zのみ。wは後で指定
    

    vout = [0,0,0,0, 0,0,0,0]
    trns.transform vin, vout, true    # w=1
    assert_in_delta 2, vout[0], 0.00001
    assert_in_delta 4, vout[1], 0.00001
    assert_in_delta 6, vout[2], 0.00001
    assert_in_delta 1, vout[3], 0.00001
    assert_in_delta 5, vout[4], 0.00001
    assert_in_delta 7, vout[5], 0.00001
    assert_in_delta 9, vout[6], 0.00001
    assert_in_delta 1, vout[7], 0.00001

    vout = [0,0,0,0, 0,0,0,0]
    trns.transform vin, vout, false   # w=0
    assert_in_delta 1, vout[0], 0.00001
    assert_in_delta 2, vout[1], 0.00001
    assert_in_delta 3, vout[2], 0.00001
    assert_in_delta 0, vout[3], 0.00001
    assert_in_delta 4, vout[4], 0.00001
    assert_in_delta 5, vout[5], 0.00001
    assert_in_delta 6, vout[6], 0.00001
    assert_in_delta 0, vout[7], 0.00001
  end

  def test_post_scale
    trns = M3G::Transform.new
    trns.post_scale 2,3,4

    v = [1,1,1,1]
    trns.transform v
    assert_in_delta 2, v[0], 0.00001
    assert_in_delta 3, v[1], 0.00001
    assert_in_delta 4, v[2], 0.00001
    assert_in_delta 1, v[3], 0.00001
  end

  def test_post_translate
    trns = M3G::Transform.new
    trns.post_translate 2,3,4

    v = [1,1,1,1]
    trns.transform v
    assert_in_delta 3, v[0], 0.00001
    assert_in_delta 4, v[1], 0.00001
    assert_in_delta 5, v[2], 0.00001
    assert_in_delta 1, v[3], 0.00001
  end

  def test_post_rotate
    trns = M3G::Transform.new
    trns.post_rotate 45, 1, 0, 0

    v = [0,0,-1,1]
    trns.transform v
    
    assert_in_delta  0.0,       v[0], 0.00001
    assert_in_delta  0.7071068, v[1], 0.00001
    assert_in_delta -0.7071068, v[2], 0.00001
    assert_in_delta 1,          v[3], 0.00001
  end

  def test_post_rotate_quaternion
    trns = M3G::Transform.new

    # q = Quaternion.new 90, 0,1,0
    q = [0, 0.707107, 0, 0.707107]
    trns.post_rotate_quat q[0], q[1], q[2], q[3]

    v = [-1,0,0,1]
    trns.transform v
    
    assert_in_delta  0.0, v[0], 0.00001
    assert_in_delta  0.0, v[1], 0.00001
    assert_in_delta  1.0, v[2], 0.00001
    assert_in_delta  1,   v[3], 0.00001
  end

  def test_post_multiply
    trns1 = M3G::Transform.new
    trns1.post_translate 1,0,0
    trns2 = M3G::Transform.new
    trns2.post_rotate    90, 1,0,0
    trns2.post_multiply  trns1

    v = [0,1,0,1]
    trns2.transform v

    assert_in_delta 1.0, v[0], 0.00001
    assert_in_delta 0.0, v[1], 0.00001
    assert_in_delta 1.0, v[2], 0.00001
    assert_in_delta 1.0, v[3], 0.00001
  end

end


